using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace BTEditor
{
    public class BTNode
    {
        /// <summary>
        /// 编辑化节点
        /// </summary>
        public EditorNode Node;
        /// <summary>
        /// 唯一识别符
        /// </summary>
        public string Guid;
        /// <summary>
        /// 节点名
        /// </summary>
        public string Label;
        /// <summary>
        /// 节点状态 . 错误类型
        /// </summary>
        public ErrorType ErrorType
        {
            get { return Node.GetIsVaild(); }
        }
        /// <summary>
        /// 节点Rect定义
        /// </summary>
        public BTNodeGraph BTNodeGraph;       
        /// <summary>
        /// 子节点
        /// </summary>
        public List<BTNode> ChildNodeList;
        /// <summary>
        /// 是否拥有子节点
        /// </summary>
        public bool IsHaveChild
        {
            get { return ChildNodeList.Count > 0; }
        }
        /// <summary>
        /// 节点类型
        /// </summary>
        public Type NodeType
        {
            get { return Node.GetType(); }
        }
        /// <summary>
        /// 节点枚举类型
        /// </summary>
        public EditorNodeEnum NodeEnum
        {
            get { return Node.NodeEnum; }
        }
        /// <summary>
        /// 默认 取第一个子节点
        /// </summary>
        public EditorNode DefaultNode
        {
            get
            {
                if (IsHaveChild)
                {
                    return ChildNodeList[0].Node;
                }

                return null;
            }
        }
        /// <summary>
        /// 实际Rect范围
        /// </summary>
        public Rect RealRect
        {
            get { return BTNodeGraph.RealRect; }
        }
        /// <summary>
        /// 节点范围
        /// </summary>
        public Rect NodeRect
        {
            get
            {
                Rect ret = RealRect;
                ret.position += BTEditorProperty.Instance.Position;
                return ret;
            }
            set { BTNodeGraph.RealRect = value; }
        }
        
        public Rect DownPointRect
        {
            get { return BTNodeGraph.DownPointRect; }
        }

        public Rect UpDownRect
        {
            get { return BTNodeGraph.UpDownRect; }
        }
        /// <summary>
        /// 是否是根节点
        /// </summary>
        public bool IsRoot => Label == "Root";
        /// <summary>
        /// 是否可以拖拽
        /// </summary>
        private bool mCanDragMove = false;
        /// <summary>
        /// 是否拖拽中
        /// </summary>
        private bool mIsDragging = false;
        
        public BTNode(string label,EditorNode node, Rect rect)
        {
            BTNodeGraph = new BTNodeGraph();  
            Label = label;
            BTNodeGraph.RealRect = rect;
            SetEditorNode(node);
            InitNode();
        }

        public void SetEditorNode(EditorNode editorNode)
        {
            Node = editorNode;
            Node.SetBelongNode(this);
        }
        
        public bool ContainChild(BTNode child)
        {
            return ChildNodeList.Contains(child);
        }

        public void AddChild(BTNode child)
        {
            if (!ContainChild(child))
            {
                ChildNodeList.Add(child);
            }
        }
        
        public void RemoveChild(BTNode child)
        {
            if (ContainChild(child))
            {
                ChildNodeList.Remove(child);
            }
        }


        private void InitNode()
        {
            ChildNodeList = new List<BTNode>();
            Guid = BTUtils.GenerateUniqueStringID();
            Node.SetBelongNode(this);
        }
                
        public void Update(Rect canvas)
        {
            DrawNode();
            DealHandles(canvas);
        }
        
        private void DrawNode()
        {
            GUIStyle style = BTEditorProperty.Instance.GetIsSelectNode(this) ? BTNodeStyle.SelectStyle : BTNodeStyle.NormalStyle;
            EditorGUI.LabelField(NodeRect, Label, style);      
            switch (ErrorType)
            {
                case ErrorType.Warn:
                    GUI.DrawTexture(BTNodeGraph.ErrorRect,BTNodeStyle.WarnPoint);
                    break;
                case ErrorType.Error:
                    GUI.DrawTexture(BTNodeGraph.ErrorRect,BTNodeStyle.ErrorPoint);
                    break;
                case ErrorType.None:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        
         /// <summary>
        /// 处理事件
        /// </summary>
        private void DealHandles(Rect canvas)
        {
            Event currentEvent = BTEditorProperty.Instance.Event;
            if (currentEvent.isMouse && currentEvent.type == EventType.MouseDrag && currentEvent.button == 0)
            {
                //拖拽
                if (NodeRect.Contains(currentEvent.mousePosition)&&mCanDragMove)
                {
                    mIsDragging = true;
                    currentEvent.Use();
                    BTEditorProperty.Instance.AddSelectNode(Guid, this);
                    BTNodeGraph.RealRect.position += currentEvent.delta;
                }
            }
            else if (currentEvent.isMouse && currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
            {
                //点击
                if (NodeRect.Contains(currentEvent.mousePosition))
                {
                    BTEditorProperty.Instance.AddSelectNode(this);
                    mCanDragMove = true;
                }
                else
                {
                    if (currentEvent.mousePosition.x<=canvas.width-BTEditorConst.LEFT_INSPECT_WIDTH)
                    {
                       BTEditorProperty.Instance.RemoveSelectNode(this);
                    }
                }
            }
            else if (currentEvent.isMouse && currentEvent.type == EventType.MouseUp && currentEvent.button == 0)
            {
                //松开鼠标
                if (mIsDragging)
                {
                    currentEvent.Use();
                    mIsDragging = false;
                }
                mCanDragMove = false;
            }
            else if (currentEvent.type == EventType.ContextClick)
            {
                if (NodeRect.Contains(currentEvent.mousePosition))
                {
                    //显示右键菜单
                    GenericMenu menu = new GenericMenu();                    
                    BTUtils.ShowMenuClick(menu,ChildNodeList.Count >= Node.CanAddNodeCount);
                    currentEvent.Use();
                }
            }
        }
    }
}